package cn.fengwoo.springBoot.utils.frequent;

import org.springframework.util.StringUtils;

import javax.imageio.*;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.ImageInputStream;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.io.*;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Util {

    // 判断一个集合是否为空
    public static <T> boolean isEmpty(Collection<T> col) {
        if (col == null || col.isEmpty()) {
            return true;
        }

        return false;
    }

    // 判断一个集合是否不为空
    public static <T> boolean isNotEmpty(Collection<T> col) {
        return !isEmpty(col);
    }

    // 判断Map是否为空
    public static <K, V> boolean isEmpty(Map<K, V> map) {
        if (map == null || map.isEmpty()) {
            return true;
        }

        return false;
    }

    // 判断Map是否不为空为空
    public static <K, V> boolean isNotEmpty(Map<K, V> map) {
        return !isEmpty(map);
    }

    // 去除list中的重复数据
    public static <T> List<T> removeRepeat(List<T> list) {
        if (isEmpty(list)) {
            return list;
        }

        List<T> result = new ArrayList<T>();
        for (T e : list) {
            if (!result.contains(e)) {
                result.add(e);
            }
        }

        return result;
    }

    // 将集合转换为String数组
    public static <T> String[] toArray(List<T> list) {
        if (isEmpty(list)) {
            return null;
        }

        String[] result = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            result[i] = String.valueOf(list.get(i));
        }

        return result;
    }

    /**
     * 获取随机数
     *
     * @param count
     * @return
     */

    public static String getRandomByCount(int count) {
        String charValue = "";
        for (int i = 0; i < count; i++) {
            char c = (char) (randomInt(1, 10) + '0');
            charValue += String.valueOf(c);
        }
        return charValue;
    }

    /**
     * 判断分页有没传值
     *
     * @param page
     * @return
     */
    public static Integer setPage(Integer page) {
        if (page == null || page <= 0) {
            page = 1;
        }
        return page;
    }

    /**
     * 判断分页有没传值
     * @param rows
     * @return
     */
    public static Integer setRows(Integer rows) {
        if (rows == null || rows <= 0) {
            rows = 20;
        }
        return rows;
    }

    /**
     * 生成订单号
     */
    public static String getOrderNumber() {
        Date date = new Date();
        SimpleDateFormat formats = new SimpleDateFormat("yyyyMMddhhmmss");
        String str = formats.format(date);

        int a = (int) (Math.random() * 9000 + 1000);

        return str + a;
    }

    public final static SimpleDateFormat Y_M_DHMS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static final boolean CutImage = false;

    public static int randomInt(int from, int to) {
        Random r = new Random();
        return from + r.nextInt(to - from);
    }

    /**
     * 验证邮箱
     *
     * @param email
     * @return
     */
    public static boolean checkEmail(String email) {
        boolean flag = false;
        try {
            String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
            Pattern regex = Pattern.compile(check);
            Matcher matcher = regex.matcher(email);
            flag = matcher.matches();
        } catch (Exception e) {
            flag = false;
        }
        return flag;
    }

    public static String getSerial(Date date, int index) {
        long msel = date.getTime();
        SimpleDateFormat fm = new SimpleDateFormat("MMddyyyyHHmmssSS");
        msel += index;
        date.setTime(msel);
        String serials = fm.format(date);
        return serials;
    }

    // 检查是否是图片格式
    public static boolean checkIsImage(String imgStr) {
        boolean flag = false;
        if (imgStr != null) {
            if (imgStr.equalsIgnoreCase(".gif") || imgStr.equalsIgnoreCase(".jpg") || imgStr.equalsIgnoreCase(".jpeg")
                    || imgStr.equalsIgnoreCase(".png")) {
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 检查是否是合法的手机号码
     *
     * @param phone
     * @return
     */
    public static boolean checkPhone(String phone) {
        if (phone == null || phone.length() < 11) {
            return false;
        }
        Pattern p = Pattern.compile("^((13[0-9])|(14[0-9])|(17[0-9])|(15[0-9])|(18[0-9]))\\d{8}$");
        Matcher m = p.matcher(phone);
        boolean result = m.matches();
        if (result == false) {
            return false;
        }
        return true;
    }

    // 检查是否是flash格式
    public static boolean checkIsFlash(String flashStr) {
        boolean flag = false;
        if (flashStr != null) {
            if (flashStr.equalsIgnoreCase(".swf") || flashStr.equalsIgnoreCase(".flv")
                    || flashStr.equalsIgnoreCase(".fla") || flashStr.equalsIgnoreCase(".f4v")) {
                flag = true;
            }
        }
        return flag;
    }

    public static byte[] compressPic(byte[] data) {
        ByteArrayInputStream is = new ByteArrayInputStream(data);

        BufferedImage src = null;
        ByteArrayOutputStream out = null;
        ImageWriter imgWrier;
        ImageWriteParam imgWriteParams;

        // 指定写图片的方式为 jpg
        imgWrier = ImageIO.getImageWritersByFormatName("jpg").next();
        imgWriteParams = new javax.imageio.plugins.jpeg.JPEGImageWriteParam(null);
        // 要使用压缩，必须指定压缩方式为MODE_EXPLICIT
        imgWriteParams.setCompressionMode(imgWriteParams.MODE_EXPLICIT);
        // 这里指定压缩的程度，参数qality是取值0~1范围内，
        imgWriteParams.setCompressionQuality((float) 0.5);

        imgWriteParams.setProgressiveMode(imgWriteParams.MODE_DISABLED);
        ColorModel colorModel = ColorModel.getRGBdefault();
        // 指定压缩时使用的色彩模式
        imgWriteParams.setDestinationType(
                new ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(32, 32)));

        try {
            src = ImageIO.read(is);
            out = new ByteArrayOutputStream(data.length);

            imgWrier.reset();
            // 必须先指定 out值，才能调用write方法, ImageOutputStream可以通过任何 OutputStream构造
            imgWrier.setOutput(ImageIO.createImageOutputStream(out));
            // 调用write方法，就可以向输入流写图片
            imgWrier.write(null, new IIOImage(src, null, null), imgWriteParams);

            out.flush();
            out.close();
            is.close();
            data = out.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return data;

    }

    /**
     * 两个时间相差2小时
     *
     * @param oldtime
     * @param newTime
     * @return
     */
    public static boolean dateDiffer(Date oldtime, Date newTime) {
        long between = oldtime.getTime() - newTime.getTime();
        if (between <= (2 * 3600000)) {
            return true;
        }
        return false;
    }

    public static boolean checkUsername(String username) {

        if (username == null || username.length() < 6) {

            return false;
        }
        // 字母开头，字母和数字
        Pattern pattern = Pattern.compile("[a-zA-Z]+[a-zA-Z0-9_]*");
        Matcher matcher = pattern.matcher(username);
        boolean result = matcher.matches();

        if (result == false) {

            return false;
        }

        return true;

    }

    public static boolean checkChinese(String name) {
        Pattern pattern = Pattern.compile("[\u4E00-\u9FA5]");
        Matcher matcher = pattern.matcher(name);
        if (matcher.find()) {
            return true;
        }
        return false;
    }

    public static String imgWidthHeight(String imgPath) throws FileNotFoundException, IOException {
        File file = new File(imgPath);
        if (file.exists() && !file.isDirectory()) {
            BufferedImage sourceImg = ImageIO.read(new FileInputStream(imgPath));
            return sourceImg.getWidth() + "*" + sourceImg.getHeight();
        }
        return "0*0";
    }

    public static String UUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 数组转字符串
     *
     * @param arras
     * @param flag
     * @return
     */
    public static String join(String arras[], String flag) {
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; arras != null && i < arras.length; i++) {
            if (arras.length - 1 == i) {
                stringBuffer.append(arras[i]);
            } else {
                stringBuffer.append(arras[i]).append(flag);
            }
        }
        return stringBuffer.toString();
    }







    /**
     * @param @param  imageUrl
     * @param @return
     * @return String
     * @throws @date 2016年8月30日下午4:16:23
     * @Title: CutImage
     * @author Jimmy
     * @Description: 截取数组中的图片
     */
    public static String transformImage(List list) {
        if (list == null || (list != null && list.size() == 0)) {
            return null;
        }
        String newImageUrl = null;
        StringBuffer avatorImgUr = new StringBuffer();
        for (Object object : list) {
            int beginIndex = 0;
            beginIndex = object.toString().indexOf("files");
            newImageUrl = object.toString().substring(beginIndex, object.toString().length());
            avatorImgUr.append(newImageUrl).append(",");
        }
        newImageUrl = avatorImgUr.substring(0, avatorImgUr.length() - 1);
        return newImageUrl;
    }

    /**
     * @param @param  date
     * @param @return
     * @param @throws ParseException
     * @return Date
     * @throws @date 2016年9月8日下午3:09:11
     * @Title: transformDate
     * @author Jimmy
     * @Description: 转换日期
     */
    public static Date transformDate(String date) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        Date newdate = simpleDateFormat.parse(date);

        return newdate;
    }

    public static int countNum(List classifyList, String compile) {
        String numstr = classifyList.toString();
        // String numstr = Arrays.toString(classifyList);// 把数组变成一个字符串[1, 3, 2,
        // 8, 5, 5, 1, 1]
        Pattern rex = Pattern.compile(compile);// 创建正则表达之对象匹配"1"
        Matcher m = rex.matcher(numstr);// 匹配numstr字符串的匹配器
        int count = 0;// 计数器，看匹配上了几个
        while (m.find()) { // find()方法从字符串中匹配"1" 找到返回true
            count += 1; // 找到1个 计数器值加 1
        }
        return count;
    }

    /**
     * @param @param  workTime
     * @param @param  classifyId
     * @param @return
     * @return int
     * @throws @date 2016年9月8日下午5:49:39
     * @Title: 计算工期
     * @author Jimmy
     * @Description: 计算工期
     */
    public static int worktime(List<Map<String, String>> workTime, String classifyId) {
        for (int i = 0; i < workTime.size(); i++) {
            if (classifyId.equals(workTime.get(i).get("classify_id"))) {
                return Integer.valueOf((workTime.get(i).get("work_time")));
            }
        }
        return 0;
    }

    /**
     * @Description: 计算造价金额
     * @date 2016年9月26日下午3:08:31
     */
    public static float rate(List<Map<String, Object>> budgetList, Integer engineeringCost) {
        for (int i = 0; i < budgetList.size(); i++) {
            Integer startingMoney = Integer.valueOf((String) budgetList.get(i).get("starting_money"));
            Integer endingMoney = Integer.valueOf((String) budgetList.get(i).get("ending_money"));
            if (engineeringCost >= startingMoney && engineeringCost < endingMoney) {
                Float rate = (Float) budgetList.get(i).get("rate");
                return rate;
            }
        }
        return 0;
    }

    /**
     * @Description:删除字符串中的某个字符
     * @date 2016年10月4日上午11:33:39
     */
    public static String delString(String oldString, String replacement) {
        String[] split = oldString.split(",");
        String newString = "";
        if (split.length == 1) {
        } else {

            String regex = "," + replacement + "|" + replacement + ",";
            System.out.println(regex);
            newString = oldString.replaceAll(regex, "");
        }
        return newString;
    }

    /**
     * @param classifyList 工种集合
     * @param key          关键字
     * @return int
     * @Description: 获取工种id
     * @date 2016年12月12日上午8:50:52
     * @auth Jimmy
     */
    public static int getClassifyId(List<Map<String, Object>> classifyList, String key) {
        for (int i = 0; i < classifyList.size(); i++) {
            if (((String) classifyList.get(i).get("text")).contains(key)) {
                return (Integer) (classifyList.get(i).get("id"));
            }
        }
        return 0;
    }

    /**
     * 校验银行卡卡号
     *
     * @param cardId
     * @return
     */
    public static boolean checkBankCard(String cardId) {
        char bit = getBankCardCheckCode(cardId.substring(0, cardId.length() - 1));
        if (bit == 'N') {
            return false;
        }
        return cardId.charAt(cardId.length() - 1) == bit;
    }

    /**
     * 从不含校验位的银行卡卡号采用 Luhm 校验算法获得校验位
     *
     * @param nonCheckCodeCardId
     * @return
     */
    public static char getBankCardCheckCode(String nonCheckCodeCardId) {
        if (nonCheckCodeCardId == null || nonCheckCodeCardId.trim().length() == 0
                || !nonCheckCodeCardId.matches("\\d+")) {
            // 如果传的不是数据返回N
            return 'N';
        }
        char[] chs = nonCheckCodeCardId.trim().toCharArray();
        int luhmSum = 0;
        for (int i = chs.length - 1, j = 0; i >= 0; i--, j++) {
            int k = chs[i] - '0';
            if (j % 2 == 0) {
                k *= 2;
                k = k / 10 + k % 10;
            }
            luhmSum += k;
        }
        return (luhmSum % 10 == 0) ? '0' : (char) ((10 - luhmSum % 10) + '0');
    }

    public static Integer parseInt(String param) {
        if (!StringUtils.isEmpty(param)) {
            return Integer.valueOf(param);
        } else {
            return null;
        }
    }

    public static String parseStr(Integer param) {
        if (param != null) {
            return String.valueOf(param);
        } else {
            return null;
        }
    }

    public static int getInt(String s, int defval) {
        if (s == null || s == "" || s.equals("null")) {
            return (defval);
        }
        try {
            return (Integer.valueOf(s));
        } catch (NumberFormatException e) {
            return (defval);
        }
    }

    public static String getStr(String s, String defval) {
        if (s == null || s == "" || s.contains("null")) {
            return (defval);
        } else {
            return s.trim();
        }
    }

    /**
     * @param request
     * @return
     * @throws UnknownHostException String
     * @Description:获取IP地址
     * @date 2016年12月12日上午8:49:16
     * @auth Jimmy
     */
    public static String getIpAddr(HttpServletRequest request) throws UnknownHostException {
        String ipAddress = null;
        String ipType = "x-forwarded-for";
        ipAddress = request.getHeader("x-forwarded-for");
        if (StringUtils.isEmpty(ipAddress) || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("X-Real-IP");
            ipType = "X-Real-IP";
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
            ipType = "WL-Proxy-Client-IP";
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            ipType = "RemoteAddr";
            if (ipAddress.equals("127.0.0.1")) {
                // 根据网卡取本机配置的IP
                InetAddress inet = null;
                inet = InetAddress.getLocalHost();

                ipAddress = inet.getHostAddress();
            }

        }

        // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ipAddress != null && ipAddress.length() > 190) {
            ipAddress = ipAddress.substring(ipType.length());
        }
        // ipAddress = ipType + ipAddress;
        return ipAddress;
    }

    /**
     * @param string 判断的字符串
     * @return boolean
     * @Description: 判断字符串是否包含特殊字符
     * @date 2016年12月12日上午8:51:27
     * @auth Jimmy
     */
    public static boolean isConSpeCharacters(String string) {
        if (string.replaceAll("[\u4e00-\u9fa5]*[a-z]*[A-Z]*\\d*-*_*\\s*", "").length() == 0) {
            // 不包含特殊字符
            return false;
        }
        return true;
    }


    /***
     *
     * 功能 :按照正方形缩放图片，精度较高
     *
     * 处理150X150或者960X960
     *
     * @param srcImgPath
     *            原图片路径
     *
     * @param distImgPath
     *            转换大小后图片路径
     *
     * @param width
     *            转换后图片宽度
     *
     * @param height
     *            转换后图片高度
     *
     */
    public static void resizeImage(String srcImgPath, String distImgPath, int width, int height) throws IOException {

        String subfix = "jpg";
        subfix = srcImgPath.substring(srcImgPath.lastIndexOf(".") + 1, srcImgPath.length());
        File srcFile = new File(srcImgPath);
        Image srcImg = ImageIO.read(srcFile);

        BufferedImage buffImg = null;
        if (subfix.equals("png")) {
            buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        } else {
            buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        }

        Graphics2D graphics = buffImg.createGraphics();
        graphics.setBackground(Color.WHITE);
        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, width, height);
        graphics.drawImage(srcImg.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);

        ImageIO.write(buffImg, subfix, new File(distImgPath));
    }

    // 裁剪图片
    public static boolean cutPic(String srcFile, String outFile, int x, int y, int width, int height) {

        FileInputStream is = null;
        ImageInputStream iis = null;
        try {
            // 如果源图片不存在
            if (!new File(srcFile).exists()) {
                return false;
            }

            // 读取图片文件
            is = new FileInputStream(srcFile);

            // 获取文件格式
            String ext = srcFile.substring(srcFile.lastIndexOf(".") + 1);

            // ImageReader声称能够解码指定格式
            Iterator<ImageReader> it = null;
            // it = ImageIO.getImageReadersByFormatName(ext);
            it = ImageIO.getImageReaders(new FileImageInputStream(new File(srcFile)));
            ImageReader reader = null;
            reader = it.next();

            // 获取图片流
            iis = ImageIO.createImageInputStream(is);

            // 输入源中的图像将只按顺序读取
            reader.setInput(iis, true);

            // 描述如何对流进行解码
            ImageReadParam param = null;
            param = reader.getDefaultReadParam();

            // 图片裁剪区域
            Rectangle rect = null;
            rect = new Rectangle(x, y, width, height);

            // 提供一个 BufferedImage，将其用作解码像素数据的目标
            param.setSourceRegion(rect);

            // 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象
            BufferedImage bi = null;
            bi = reader.read(0, param);

            // 保存新图片
            File tempOutFile = new File(outFile);
            if (!tempOutFile.exists()) {
                tempOutFile.mkdirs();
            }
            ImageIO.write(bi, ext, new File(outFile));

            if (bi != null) {
                bi.flush();
                bi = null;
                System.gc();
            }

            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (is != null) {
                    is.close();
                    is = null;
                }
                if (iis != null) {
                    iis.close();
                }
                System.gc();
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }
    }

    public static String decimalFormat(double d) {
        DecimalFormat df = new DecimalFormat("######0.00");
        return df.format(d);
    }

    /**
     * @param paramete1 参数1
     * @param paramete2 参数2
     * @return MD5字符串 String
     * @date 2017年1月8日下午9:42:55
     */
    public static String getToken(String paramete1, String paramete2) {
        StringBuffer stringBuffer = new StringBuffer();
        String paramete3 = "www.fengwoo.cn";
        Timestamp timestamp = DateUtils.getTimestamp();
        StringBuffer append = stringBuffer.append(paramete1).append(paramete2).append(timestamp.toString())
                .append(paramete3);
        String md5Str = Md5.getMD5Str(append.toString());
        return md5Str;
    }

    /**
     * 随机指定范围内N个不重复的数 利用HashSet的特征，只能存放不同的值
     *
     * @param min              指定范围最小值
     * @param max              指定范围最大值
     * @param n                随机数个数
     * @param set              随机数结果集
     */
    public static void randomSet(int min, int max, int n, int nOfRecursive, HashSet<Integer> set) {
        if (n > (max - min + 1) || max < min) {
            return;
        }
        for (int i = 0; i < nOfRecursive; i++) {
            Random random = new Random();
            Integer v_number = random.nextInt(max) % (max - 1 + 1) + 1;
            set.add(v_number);// 将不同的数存入HashSet中
        }
        int setSize = set.size();
        // 如果存入的数小于指定生成的个数，则调用递归再生成剩余个数的随机数，如此循环，直到达到指定大小
        if (setSize < n) {
            randomSet(min, max, n, n - setSize, set);// 递归
        }
    }

    /**
     * 获得当前日期的下一天
     *
     * @param date 当前日期
     */
    public static Date getNextDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        Date v_nextDay = new Date(calendar.getTimeInMillis());
        return v_nextDay;
    }

    public static BigDecimal getRandom() {
        double random1 = Math.random() / 10;
        int rd = Math.random() > 0.5 ? 1 : 0;
        if (rd == 1) {
            return new BigDecimal(random1);
        } else {
            return new BigDecimal(-random1);
        }
    }

    public static char getRandomChar() {
        return (char) (0x4e00 + (int) (Math.random() * (0x9fa5 - 0x4e00 + 1)));
    }


    /**
     * 获得客户端的ip地址
     *
     * @param request
     * @return
     * @author yqwang
     * @date 2017年2月22日 下午3:55:40
     */
    public static String getIp2(HttpServletRequest request) {
        if (request.getHeader("x-forwarded-for") == null) {
            return request.getRemoteAddr();
        }
        return request.getHeader("x-forwarded-for");
    }

    /**
     * 获得客户端的主机名
     *
     * @param request
     * @return
     * @author yqwang
     * @date 2017年2月22日 下午3:55:27
     */
    public static String getRemoteHost(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
    }

}
